{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2b089368-ef95-42fb-bdb8-08e0ce471816",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "## Setup and Imports\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "06ae5bc5-7f0a-4a17-9dcb-322bebe94f18",
   "metadata": {},
   "outputs": [],
   "source": [
    "# %%\n",
    "\n",
    "from langgraph.graph import StateGraph, END\n",
    "import random\n",
    "from typing import TypedDict, List\n",
    "from IPython.display import Image, display"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03f461c3-6e7e-470b-8ed7-ab5e576cf806",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "## State Definition\n",
    "\n",
    "We'll create a simple state that tracks a list of numbers and their running total. Our loop will continue adding random numbers until the total reaches a threshold.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "37efc46c-2064-49b4-a607-2301d81f622b",
   "metadata": {},
   "outputs": [],
   "source": [
    "# %%\n",
    "\n",
    "# Define the shape of our state\n",
    "class SumState(TypedDict):\n",
    "    numbers: List[int]\n",
    "    total: int"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2811db66-580c-4b0c-8318-0c25f7ffbf32",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "## Approach 1: Direct Conditional Routing\n",
    "\n",
    "In this approach, we'll create a graph where the conditional edges are attached directly to the processing node. This creates a more compact graph structure.\n",
    "\n",
    "### Node Functions\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c022541e-b21b-4c43-9c53-f572d5e829c9",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "### Building the Graph\n",
    "\n",
    "Now, we'll build the graph using direct conditional routing. Observe how the `add` node features conditional edges that can loop back to itself, forming a cycle.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e1052d97-1adc-40c9-9833-fa9c9ea9e95a",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "### Visualizing the Graph\n",
    "\n",
    "Let's visualize the graph structure to understand the flow better.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d571bdaf-eef3-4fe3-98a5-7420a198ebb8",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "### Running the Graph\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "debb7ca9-fccd-43fc-910c-838f6b658371",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "## Approach 2: Separate Decision Node\n",
    "\n",
    "In this approach, we'll use a dedicated decision node that acts as a router. This pattern separates the processing logic from the routing logic, which can be useful for more complex decision-making scenarios.\n",
    "\n",
    "### Node Functions\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3be05f61-54af-4ed0-bbf1-4c3fe7e5e964",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "### Building the Graph with Decision Node\n",
    "\n",
    "This time we'll create a more explicit flow: `init → add → decide → (add or END)`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d7bb0f1-3e8d-44f6-908b-118fdd10c07f",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "### Visualizing the Second Graph\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff460ab9-3658-4597-b60a-0b02c078b4f2",
   "metadata": {},
   "source": [
    "# %% [markdown]\n",
    "\n",
    "### Running the Second Graph\n"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": 3
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
